const logger = require('../utils/logger');

/**
 * 简单的内存限流器
 * 生产环境建议使用 Redis 实现分布式限流
 */
class RateLimiter {
  constructor(options = {}) {
    this.windowMs = options.windowMs || parseInt(process.env.RATE_LIMIT_WINDOW_MS) || 15 * 60 * 1000; // 15分钟
    this.maxRequests = options.maxRequests || parseInt(process.env.RATE_LIMIT_MAX_REQUESTS) || 100;
    this.message = options.message || '请求过于频繁，请稍后再试';
    this.requests = new Map(); // { ip: [timestamps] }
    
    // 定期清理过期记录
    setInterval(() => this.cleanup(), this.windowMs);
  }

  /**
   * 清理过期的请求记录
   */
  cleanup() {
    const now = Date.now();
    for (const [ip, timestamps] of this.requests.entries()) {
      const validTimestamps = timestamps.filter(ts => now - ts < this.windowMs);
      if (validTimestamps.length === 0) {
        this.requests.delete(ip);
      } else {
        this.requests.set(ip, validTimestamps);
      }
    }
  }

  /**
   * 检查是否超过限流
   */
  isRateLimited(ip) {
    const now = Date.now();
    const timestamps = this.requests.get(ip) || [];
    
    // 过滤掉窗口外的时间戳
    const validTimestamps = timestamps.filter(ts => now - ts < this.windowMs);
    
    // 更新记录
    this.requests.set(ip, validTimestamps);
    
    return validTimestamps.length >= this.maxRequests;
  }

  /**
   * 记录请求
   */
  recordRequest(ip) {
    const now = Date.now();
    const timestamps = this.requests.get(ip) || [];
    timestamps.push(now);
    this.requests.set(ip, timestamps);
  }

  /**
   * 中间件函数
   */
  middleware() {
    return (req, res, next) => {
      // 开发环境可通过环境变量禁用限流
      if (process.env.DISABLE_RATE_LIMIT === 'true') {
        return next();
      }

      const ip = req.ip || req.connection.remoteAddress;
      
      if (this.isRateLimited(ip)) {
        logger.warn(`IP ${ip} 触发限流`, { 
          ip, 
          url: req.originalUrl,
          method: req.method 
        });
        
        return res.status(429).json({
          code: 429,
          msg: this.message,
          retryAfter: Math.ceil(this.windowMs / 1000)
        });
      }
      
      this.recordRequest(ip);
      next();
    };
  }
}

// 根据环境配置限流参数
const isDevelopment = process.env.NODE_ENV !== 'production';

// 创建不同级别的限流器
const generalLimiter = new RateLimiter({
  windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS) || (isDevelopment ? 1 * 60 * 1000 : 15 * 60 * 1000), // 开发: 1分钟, 生产: 15分钟
  maxRequests: parseInt(process.env.RATE_LIMIT_MAX_REQUESTS) || (isDevelopment ? 1000 : 100), // 开发: 1000次, 生产: 100次
  message: '请求过于频繁，请稍后再试'
});

const strictLimiter = new RateLimiter({
  windowMs: isDevelopment ? 1 * 60 * 1000 : 15 * 60 * 1000, // 开发: 1分钟, 生产: 15分钟
  maxRequests: isDevelopment ? 200 : 20, // 开发: 200次, 生产: 20次
  message: '该操作过于频繁，请稍后再试'
});

const uploadLimiter = new RateLimiter({
  windowMs: isDevelopment ? 10 * 60 * 1000 : 60 * 60 * 1000, // 开发: 10分钟, 生产: 1小时
  maxRequests: isDevelopment ? 500 : 50, // 开发: 500次, 生产: 50次
  message: '上传过于频繁，请稍后再试'
});

module.exports = {
  RateLimiter,
  generalLimiter: generalLimiter.middleware(),
  strictLimiter: strictLimiter.middleware(),
  uploadLimiter: uploadLimiter.middleware()
};

